package com.chinaoct.siku.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;

@Slf4j
public class HttpRequest {


    private static long timeMillis=System.currentTimeMillis();
    private static CloseableHttpClient client = null;


    public static CloseableHttpClient getHttpClient() {
        if(null==client) {
            init();
        }
        return client;
    }

    private static void init() {
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(30000)
                .setConnectionRequestTimeout(30000).build();
        client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
    }

    public static String postForForm(String url, Map<String, String> parms){
        String result = null;

        CloseableHttpClient httpClient = getHttpClient();
        HttpPost httppost = new HttpPost(url);
        ArrayList<BasicNameValuePair> list = new ArrayList<>();
        parms.forEach((key, value) -> list.add(new BasicNameValuePair(key, value)));
        try {
            if (Objects.nonNull(parms) && parms.size() >0) {
                httppost.setEntity(new UrlEncodedFormEntity(list, "UTF-8"));
            }
            HttpResponse response = httpClient.execute(httppost);
            int code = response.getStatusLine().getStatusCode();
            if(code==200){
                result = EntityUtils.toString(response.getEntity(),"utf-8");
                return result;
            }else {
                return null;
            }

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (null != httppost)
                httppost.releaseConnection();
        }
        return result;

    }




    public static String doPost(String url, String param) {
        String result = null;

        CloseableHttpClient httpClient = getHttpClient();
        HttpPost httppost = new HttpPost(url);
        httppost.setHeader("Content-Type", "application/json; charset=utf-8");
        try {
            StringEntity entity = new StringEntity(param, "utf-8");
            httppost.setEntity(entity);
            HttpResponse response = httpClient.execute(httppost);
            int code = response.getStatusLine().getStatusCode();
            if(code==200){
                result = EntityUtils.toString(response.getEntity(),"utf-8");
                return result;
            }else {
                return null;
            }

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (null != httppost)
                httppost.releaseConnection();
        }
        return result;
    }

    public static String doPost(String url, String param,HttpClientContext context) {
        String result = null;

        HttpClient httpClient = getHttpClient();
        HttpPost httppost = new HttpPost(url);
        httppost.setHeader("Content-Type", "application/json; charset=utf-8");
        try {
            StringEntity entity = new StringEntity(param, "utf-8");
            httppost.setEntity(entity);
            HttpResponse response = httpClient.execute(httppost,context);
            int code = response.getStatusLine().getStatusCode();
            if(code==200){
                result = EntityUtils.toString(response.getEntity(),"utf-8");
                return result;
            }else {
                return null;
            }

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (null != httppost)
                httppost.releaseConnection();
        }
        return result;
    }

    /**
     * post提交json
     * @param url
     * @param param
     * @return
     */
    public static String postJson(String url,String param) throws Exception{
        String result=null;

        CloseableHttpClient client = getHttpClient();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).
                setConnectTimeout(60000).build();//设置请求和传输超时时间
        HttpPost httppost = new HttpPost(url);
        httppost.setConfig(requestConfig);
        httppost.setHeader("Content-Type", "application/json; charset=utf-8");
        try {
            StringEntity entity = new StringEntity(param, "utf-8");
            httppost.setEntity(entity);
            HttpResponse response = client.execute(httppost);
            int code = response.getStatusLine().getStatusCode();
            if(code==200){
                result = EntityUtils.toString(response.getEntity(),"utf-8");
                return result;
            }else {
                if(null!=response.getEntity()){
                    String page = EntityUtils.toString(response.getEntity());
                    throw new Exception(page);
                }
            }
        } finally{
            if (null != httppost)
                httppost.releaseConnection();
            client = null;
            requestConfig=null;
        }

        return result;
    }

    /**
     * get方法
     * @param url
     * @return
     * @throws IOException
     * @throws ClientProtocolException
     */
    public static String doGet(String url) throws Exception{
        String result=null;
        CloseableHttpClient client = getHttpClient();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).
                setConnectTimeout(60000).build();//设置请求和传输超时时间
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(requestConfig);
        try {
            HttpResponse response = client.execute(httpGet);
            int code = response.getStatusLine().getStatusCode();
            result = EntityUtils.toString(response.getEntity(),"utf-8");
            return result;
//            if(code==200){
//                result = EntityUtils.toString(response.getEntity(),"utf-8");
//                return result;
//            }else {
//                if(null!=response.getEntity()){
//                    String page = EntityUtils.toString(response.getEntity());
//                    throw new Exception(page);
//                }
//            }
        } finally{
            if (null != httpGet)
                httpGet.releaseConnection();
            client = null;
            requestConfig=null;
        }
       // return null;
    }

    public static String delete(String url)throws Exception{
        String result=null;
        CloseableHttpClient client = getHttpClient();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(45000).
                setConnectTimeout(45000).build();//设置请求和传输超时时间
        HttpDelete httpdelete= new HttpDelete(url);
        httpdelete.setConfig(requestConfig);
        try {
            HttpResponse response = client.execute(httpdelete);
            int code = response.getStatusLine().getStatusCode();
            if(code==200){
                result = EntityUtils.toString(response.getEntity(),"utf-8");
                return result;
            }else {
                if(null!=response.getEntity()){
                    String page = EntityUtils.toString(response.getEntity());
                    throw new Exception(page);
                }
            }
        } finally{
            if (null != httpdelete)
                httpdelete.releaseConnection();
            client = null;
            requestConfig=null;
        }
        return null;
    }

    /**
     * 同步通讯录   post 传   json
     * @param url  请求地址
     * @param token
     * @param json  json 参数
     * @return
     * @throws Exception
     */
    public static Boolean dopost(String url ,String token,String json) throws Exception{
        CloseableHttpClient client = getHttpClient();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).
                setConnectTimeout(60000).build();//设置请求和传输超时时间
        if(null!=token && !"".equals(token))
            url+=token;
        HttpPost httppost = new HttpPost(url);
        httppost.setConfig(requestConfig);
        httppost.addHeader("Content-Type", "application/json;charset=UTF-8");
        httppost.addHeader("accept-language", "zh-CN,zh;q=0.8");
        try {
            if(null!=json){
                StringEntity entity = new StringEntity(json,"utf-8");
                httppost.setEntity(entity);
            }
            HttpResponse response=client.execute(httppost);
            int code = response.getStatusLine().getStatusCode();
            if(code==200){
                return true;
            }else {
                if(null!=response.getEntity()){
                    String page = EntityUtils.toString(response.getEntity());
                    throw new Exception(page);
                }
            }

        }finally{
            if (null != httppost)
                httppost.releaseConnection();
            client = null;
            requestConfig=null;
        }
        return false;
    }


    /**
     * 下载图片
     * @param url
     * @param localPath
     * @param name  不包括后缀
     */
    public static File downloadPicture(String url, String localPath, String name) {
        //可关闭的httpclient客户端，相当于你打开一个浏览器
        CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
        //构造httpget请求对象
        HttpGet httpGet = new HttpGet(url);
        //响应
        CloseableHttpResponse response = null;

        FileOutputStream fos = null;
        try {
            response = closeableHttpClient.execute(httpGet);
            //获取响应结果  HttpEntity不仅可以作为结果，也可以作为请求的参数实体，有很多实现
            HttpEntity entity = response.getEntity();
            int code = response.getStatusLine().getStatusCode();
            if(code!=200){
                return  null;
            }
            File dest = new File(localPath);
            // 检测是否存在目录
            if (!dest.exists()) {
                if (!dest.mkdirs()) {
                    log.error("was not successful.");
                }
            }
            String fileName = localPath + name;
            if(name.indexOf(".")<0){
                // image/jpg  image/jpeg  image/png
                String contentType = entity.getContentType().getValue();//特别注意这里要getValue一下，否则这里不是string类型的数据而是reader类型的
                String suffix = ".jpg";
                if (contentType.contains("jpeg") || contentType.contains("jpg")) {
                    suffix = ".jpg";
                } else if (contentType.contains("bmp") || contentType.contains("bitmap")) {
                    suffix = ".bmp";
                } else if (contentType.contains("png")) {
                    suffix = ".png";
                } else if (contentType.contains("gif")) {
                    suffix = ".gif";
                }

                fileName = localPath + name + suffix;
            }
            //字节流
            byte[] bytes = EntityUtils.toByteArray(entity);
            fos = new FileOutputStream(fileName);
            fos.write(bytes);

            //确保流关闭
            EntityUtils.consume(entity);
            return new File(fileName);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            return null;
        } finally {
            //关闭输出流
            if(fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (closeableHttpClient != null) {
                try {
                    closeableHttpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
